#ifndef TMS_H_
#define TMS_H_

#pragma once

#include "tms_definitions.hpp"
#include "tms_db.hpp"
#include "tms_ui.hpp"

enum AdminTimeModiMode
{
    SPOT_LAUNCH,
    SPOT_ARRIVE,
    LAUNCH_TIME,
    TICKET_PRICE,
    DURATION
};

enum UserDataModiMode
{
    NAME,
    PASSWD
};

/*
派生的主程序类
添加数据库接口的额外实现（实际上放在主程序这里的实现主要是针对数据库事务的派生）
*/
class TmsApplication : public Application
{
private:
    TmsApplication(const TmsApplication &other);

protected:
public:
    TmsDataBackend *be;

    explicit TmsApplication()
        : Application(),
          be(new TmsDataBackend(tms::TIME_TABLE_DB_FILE, tms::USER_DB_FILE, tms::SALES_DB_FILE)) {};
    virtual ~TmsApplication() { delete be; };

    virtual int mainloop();
};

/*
管理员登录选择节点
*/
class AdminPasswdSelectionNode : public SelectionNode
{
private:
    TmsApplication *app;
    const std::string ADMIN_PWD;

public:
    AdminPasswdSelectionNode(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : SelectionNode(app, n_name, par_node),
          app(app),
          ADMIN_PWD(tms::ADMIN_PASSWD) {};

    void init_loop();

    void exit_loop();
};

/*
用户登录选择节点
*/
class CustomerSelectionNode : public SelectionNode
{
private:
    TmsApplication *app;

public:
    CustomerSelectionNode(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : SelectionNode(app, n_name, par_node),
          app(app) {};

    void init_loop();

    void exit_loop();
};

/*
管理员统计数据页面
*/
class AShowStat : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    AShowStat(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
读取时间表
*/
class AReadSche : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    AReadSche(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
修改时间表项
这里为了简化类实现，使用参数控制修改项，实现对每一个参数的修改
时间表有几个选项：
始发站 spot_launch
终点站 spot_arrive
发车时间 launch_time
行车时间 duration
票价 ticket_price
销售模块和取消指示不使用这个接口实现
*/
class AModiSche : public BaseMenuNode
{
private:
    TmsApplication *app;
    AdminTimeModiMode mode;

public:
    AModiSche(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node, const AdminTimeModiMode mode = TICKET_PRICE)
        : BaseMenuNode(app, n_name, par_node),
          app(app), mode(mode) {};

    virtual int execute();
};

/*
管理员取消车次
*/
class ACancSche : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    ACancSche(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
删除时间表
设计报告要求必须要有这个功能，但是如果在行车时间中使用，必将造成系统混乱，因为无法正确跟踪取消的车次
*/
class ADeleSche : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    ADeleSche(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
管理员添加车次
*/
class AAddaNewb : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    AAddaNewb(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
管理员读取用户
*/
class AReadUser : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    AReadUser(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
管理员修改用户
*/
class AModiUser : public BaseMenuNode
{
private:
    TmsApplication *app;
    UserDataModiMode mode;

public:
    AModiUser(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node, UserDataModiMode mode = NAME)
        : BaseMenuNode(app, n_name, par_node),
          app(app),
          mode(mode) {};

    virtual int execute();
};

/*
管理员删除用户
*/
class ADeleUser : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    ADeleUser(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
管理员分析行车数据
*/
class AAnasBusd : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    AAnasBusd(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
管理员导出文日志文件
*/
class AExpoLogf : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    AExpoLogf(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
用户显示所有车次
*/
class CShowTick : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    CShowTick(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
用户搜索车票
*/
class CSearTick : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    CSearTick(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
用户购买车票
*/
class CProcTick : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    CProcTick(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
用户退订车票
*/
class CRefuTick : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    CRefuTick(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
用户修改个人信息
这个类用参数控制修改的参数类型
用户名 name
密码 passwd
*/
class CModiUser : public BaseMenuNode
{
private:
    TmsApplication *app;
    UserDataModiMode mode;

public:
    CModiUser(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node, UserDataModiMode mode = NAME)
        : BaseMenuNode(app, n_name, par_node),
          app(app), mode(mode) {};

    virtual int execute();
};

/*
用户充值
*/
class CCharMony : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    CCharMony(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
用户个人主页
*/
class CMainPane : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    CMainPane(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

/*
注册用户
*/
class OCustReg : public BaseMenuNode
{
private:
    TmsApplication *app;

public:
    OCustReg(TmsApplication *app, const std::string &n_name, BaseMenuNode *par_node)
        : BaseMenuNode(app, n_name, par_node),
          app(app) {};

    virtual int execute();
};

#endif